from typing import Dict

from sqlalchemy import Engine
from sqlalchemy.orm import Session, sessionmaker

from ctaf_core.ctaf_objects.base_exception import CTAFbaseException
from ctaf_core.data_access_bundle.datasource_create_util import create_mysql_datasource, create_sqlite_datasource
from ctaf_core.data_access_bundle.db_type_enum import DataBaseType
from ctaf_facade.enumerations.error_code_enum import ErrorCodeEnum


class DataBaseSessionFactory:
    __db_source: Engine = None

    @staticmethod
    def get_db_session() -> Session:
        session = sessionmaker(bind=DataBaseSessionFactory.__db_source)()
        return session

    @staticmethod
    def init_db_source(db_setting: Dict) :
        if DataBaseSessionFactory.__db_source is None:
            DataBaseSessionFactory.__db_source = DataBaseSessionFactory.__create_datasource(db_setting)

    @staticmethod
    def get_db_source() :
        if DataBaseSessionFactory.__db_source:
            return DataBaseSessionFactory.__db_source
        else:
            raise CTAFbaseException(ErrorCodeEnum.DB_ACCESS_ERROR)

    @staticmethod
    def __create_datasource(db_setting: Dict)-> Engine:
        if DataBaseType.MYSQL.value == db_setting["db_type"]:
            user = db_setting["db_user"]
            password = db_setting["db_password"]
            host = db_setting["db_host"]
            port = db_setting["db_port"]
            database_name = db_setting["db_name"]
            pool_size = db_setting["db_pool_size"]
            max_overflow = db_setting["db_max_overflow"]
            return create_mysql_datasource(user, password, host, port, database_name, pool_size, max_overflow)
        if DataBaseType.SQLITE.value == db_setting["db_type"]:
            database_name = db_setting["db_name"]
            return create_sqlite_datasource(database_name)